package com.csmy.my.center.dao;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.attilax.exception.ExUtil;
import com.csmy.my.center.util.CTConstants;
import com.csmy.my.center.util.CTUtils;
import com.csmy.my.center.util.StringUtil;
import com.csmy.my.center.util.dataconvert.Dto;
import com.csmy.my.center.util.dataconvert.impl.BaseDto;
import com.csmy.my.center.util.exception.G4Exception;
import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
import com.ibatis.sqlmap.engine.mapping.sql.Sql;
import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
import com.ibatis.sqlmap.engine.scope.SessionScope;
import com.ibatis.sqlmap.engine.scope.StatementScope;

/**
 * 数据访问实现类(原生)<br>
 * 基于Spring对iBatis的支持机制实现,支持自定义的数据操作
 * 
 * @author wgp
 * @since 2013-01-15
 * @see org.springframework.orm.ibatis.support.SqlMapClientDaoSupport
 */
public class DaoImpl extends SqlMapClientDaoSupport implements Dao {
	
	private static Log log = LogFactory.getLog(DaoImpl.class);

	/**
	 * 插入一条记录
	 * 
	 * @param SQL语句ID号
	 * @param parameterObject
	 *            要插入的对象(map javaBean)
	 */
	public void insert(String statementName, Object parameterObject) {
		this.printSQl(statementName,parameterObject);
		getSqlMapClientTemplate().insert(statementName, parameterObject);
	}

	/**
	 * 插入一条记录
	 * 
	 * @param SQL语句ID号
	 */
	public void insert(String statementName) {
		this.printSQl(statementName,new BaseDto());
		getSqlMapClientTemplate().insert(statementName, new BaseDto());
	}

	/**
	 * 查询一条记录
	 * 
	 * @param SQL语句ID号
	 * @param parameterObject
	 *            查询条件对象(map javaBean)
	 */
	public Object queryForObject(String statementName, Object parameterObject) {
		this.printSQl(statementName,parameterObject);
		return getSqlMapClientTemplate().queryForObject(statementName, parameterObject);
	}

	/**
	 * 查询一条记录
	 * 
	 * @param SQL语句ID号
	 */
	public Object queryForObject(String statementName) {
		this.printSQl(statementName,null);
		return getSqlMapClientTemplate().queryForObject(statementName, new BaseDto());
	}

	/**
	 * 查询记录集合
	 * 
	 * @param SQL语句ID号
	 * @param parameterObject
	 *            查询条件对象(map javaBean)
	 */
	public List queryForList(String statementName, Object parameterObject) {
		this.printSQl(statementName,parameterObject);
		return getSqlMapClientTemplate().queryForList(statementName, parameterObject);
	}

	/**
	 * 查询记录集合
	 * 
	 * @param SQL语句ID号
	 */
	public List queryForList(String statementName) {
		this.printSQl(statementName,null);
		return getSqlMapClientTemplate().queryForList(statementName, new BaseDto());
	}

	/**
	 * 按分页查询
	 * 
	 * @param SQL语句ID号
	 * @param parameterObject
	 *            查询条件对象(map javaBean)
	 * @throws SQLException 
	 */
	public List queryForPage(String statementName, Dto qDto) throws SQLException {
		Connection connection = getConnection();
		String dbNameString = connection.getMetaData().getDatabaseProductName().toLowerCase();
		try {
			connection.close();
		} catch (Exception e) {
			log.error(CTConstants.Exception_Head + "未正常关闭数据库连接");
			e.printStackTrace();
		}
		String start = qDto.getAsString("start");
		String limit = qDto.getAsString("limit");
		int startInt = 0;
		if (CTUtils.isNotEmpty(start)) {
			startInt = Integer.parseInt(start);
			if (dbNameString.indexOf("ora") > -1) {
				qDto.put("start", startInt + 1);
			} else if (dbNameString.indexOf("mysql") > -1) {
				qDto.put("start", startInt);
			} else {
				qDto.put("start", startInt);
			}
		}
		if (CTUtils.isNotEmpty(limit)) {
			int limitInt = Integer.parseInt(limit);
			if (dbNameString.indexOf("ora") > -1) {
				qDto.put("end", limitInt + startInt);
			} else if (dbNameString.indexOf("mysql") > -1) {
				qDto.put("end", limitInt);
			} else {
				qDto.put("end", limitInt);
			}
		}
		
		Integer intStart = qDto.getAsInteger("start");
		Integer end = qDto.getAsInteger("end");
		if (CTUtils.isEmpty(start) || CTUtils.isEmpty(end)) {
			try {
				throw new G4Exception(
						CTConstants.ERR_MSG_QUERYFORPAGE_STRING);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return getSqlMapClientTemplate().queryForList(statementName, qDto,
				intStart.intValue(), end.intValue());
	}

	/**
	 * 更新记录
	 * 
	 * @param SQL语句ID号
	 * @param parameterObject
	 *            更新对象(map javaBean)
	 */
	public int update(String statementName, Object parameterObject) {
		this.printSQl(statementName,parameterObject);
		return getSqlMapClientTemplate().update(statementName, parameterObject);
	}

	/**
	 * 更新记录
	 * 
	 * @param SQL语句ID号
	 */
	public int update(String statementName) {
		this.printSQl(statementName,null);
		return getSqlMapClientTemplate().update(statementName, new BaseDto());
	}

	/**
	 * 删除记录
	 * 
	 * @param SQL语句ID号
	 * @param parameterObject
	 *            更新对象(map javaBean)
	 */
	public int delete(String statementName, Object parameterObject) {
	//	try{
	//parameterObject=	{copy_id=83467585_cid, optype=delete_copy, now=1459357841919}
		this.printSQl(statementName,parameterObject);
		return getSqlMapClientTemplate().delete(statementName, parameterObject);
//		}catch(Exception e)
//		{
//			ExUtil.throwEx(e);
//		}
//		return 0;
	}

	/**
	 * 删除记录
	 * 
	 * @param SQL语句ID号
	 */
	public int delete(String statementName) {
		this.printSQl(statementName,null);
		return getSqlMapClientTemplate().delete(statementName, new BaseDto());
	}

	/**
	 * 获取Connection对象<br>
	 * 说明：虽然向Dao消费端暴露了获取Connection对象的方法但不建议直接获取Connection对象进行JDBC操作
	 * 
	 * @return 返回Connection对象
	 * @throws SQLException
	 */
	public Connection getConnection() throws SQLException {
		return getSqlMapClientTemplate().getDataSource().getConnection();
	}

	/**
	 * 获取DataSource对象<br>
	 * 说明：虽然向Dao消费端暴露了获取DataSource对象的方法但不建议直接获取DataSource对象进行JDBC操作
	 * 
	 * @return 返回DataSource对象
	 */
	public DataSource getDataSourceFromSqlMap() throws SQLException {
		return getSqlMapClientTemplate().getDataSource();
	}

	/**
	 * 获取SqlMapClientTemplate对象<br>
	 * 
	 * @return 返回SqlMapClientTemplate对象
	 */
	public SqlMapClientTemplate getSqlMapClientTpl() {
		return getSqlMapClientTemplate();
	}
	
	
	/**
	 * 打印sql语句
	 * @param sqlName
	 * @param params
	 */
	private void printSQl(String sqlName,Object params){
		SqlMapClientTemplate sqlMapClientTemplate = getSqlMapClientTemplate();
		SqlMapClientImpl sqlMapClientImpl = (SqlMapClientImpl) sqlMapClientTemplate.getSqlMapClient();
		MappedStatement mappedStatement = sqlMapClientImpl.getMappedStatement(sqlName);

		Sql sql = mappedStatement.getSql();
		StatementScope ss = new StatementScope(new SessionScope());
		mappedStatement.initRequest(ss);
		String sqlString = sql.getSql(ss, params);
		StringUtil.xprint("执行【sqlname="+sqlName+"】，SQL语句为→"+sqlString);
		
		if (logger.isDebugEnabled()) logger.debug(params);
		if (logger.isDebugEnabled()) logger.debug(sqlString);
		logger.error("执行【sqlname="+sqlName+"】，SQL语句为→"+sqlString);		
	}
}
